﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Xml.Linq;
using Puzzler.Common;
using Puzzler.Common.Exceptions;
using Puzzler.Plugin.Interface.Attributes;

namespace Puzzler.Plugin.Interface
{
    /// <summary>
    /// Represent the data model for a puzzle plugin. <b>Must contains constructor with: PuzzleData</b>
    /// </summary>
    public abstract class PuzzleModel : DependencyObject, IPuzzleModel
    {
        public static readonly DependencyProperty CaptionProperty =
            DependencyProperty.Register("Caption", typeof (String), typeof (PuzzleModel), new PropertyMetadata(default(String)));

        public String Caption
        {
            get { return (String) GetValue(CaptionProperty); }
            set { SetValue(CaptionProperty, value); }
        }

        public static readonly DependencyProperty CommentProperty =
            DependencyProperty.Register("Comment", typeof (String), typeof (PuzzleModel), new PropertyMetadata(default(String)));

        public String Comment
        {
            get { return (String) GetValue(CommentProperty); }
            set { SetValue(CommentProperty, value); }
        }

        public static readonly DependencyProperty StateProperty =
            DependencyProperty.Register("State", typeof (PuzzleState), typeof (PuzzleModel), new PropertyMetadata(PuzzleState.Created));

        public PuzzleState State
        {
            get { return (PuzzleState) GetValue(StateProperty); }
            set { SetValue(StateProperty, value); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private PuzzleModelAttribute ownAttribute;

        protected PuzzleModelAttribute OwnAttribute
        {
            get { return ownAttribute; }
        }

        protected PuzzleModel()
        {
            ownAttribute = AttributeUtils.ExtractSingleAttribute<PuzzleModelAttribute>(GetType(), false);
        }

        protected sealed override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            OnPropertyChanged(e.Property.Name);
        }

        protected void OnPropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        

        public virtual void Update(PuzzleData data)
        {
            Caption = data.Caption;
        }

        #region Plugin Action

        public virtual void OnInitialized()
        {
        }

        public virtual void OnDone()
        {
        }

        public virtual void OnActivated()
        {
        }

        public virtual void OnDeactivated()
        {
        }

        #endregion
    }
}
